using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using TLDRML.Nodes;

namespace TLDRML
{
    public class XmlGeneratorVisitor : INodeVisitor
    {
        private readonly XmlTextWriter _xmlOut;
        private readonly Dictionary<Type, Action<Node>> _nodeHandler = new Dictionary<Type, Action<Node>>();
        private readonly Stack<Action> _closeActions = new Stack<Action>();

        public XmlGeneratorVisitor(TextWriter textWriter)
        {
            _xmlOut = new XmlTextWriter(textWriter)
                      {
                          Formatting = Formatting.Indented,
                          Indentation = 2
                      };

            _nodeHandler[typeof(ElementNode)] = HandleElement;
        }

        public void Visit(Node node)
        {
            Type type = node.GetType();

            if (_nodeHandler.ContainsKey(type))
                _nodeHandler[type](node);
            else
                _closeActions.Push(NoAction);
        }

        public void Descend()
        {
        }

        public void Ascend()
        {
            _closeActions.Pop()();
        }

        protected static void NoAction()
        {
        }

        private void HandleElement(Node node)
        {
            var element = (ElementNode)node;

            _xmlOut.WriteStartElement(element.Type);

            foreach (var attr in element.AttributeNodes)
                _xmlOut.WriteAttributeString(attr.Name, attr.Value);

            _closeActions.Push(() => _xmlOut.WriteEndElement());
        }
    }
}